在上一个HDMI的基础上进行修改硬件:
由于 ZYNQ的PS 调用EMIO方式 默认输出是GMII,而我们的网络部分(转接卡)的芯片 RTL8211是 输出RGMII的,所以这里我们需要增加一个 GMII和RGMII转换的IP模块 (Gmii to Rgmii)
打开 GMII TO RGMII模块 设置更改成下面
又因为GMII TO RGMII 是高电平复位 ,但是ZYNQ 是输出低电平复位的,所以这里需要增加一个反相器(搜索utility, 在检索出来的选项里 选择 utility vector logic)
在设置页里改成 not(反相器)将位宽改成1
由于网口的配置要求和HDMI的配置要求有冲突,我们需要修改一下对ZYNQ的设置:
按下图进行连接:
block design 修改完成后保存,然后重新 Generate Output Products 和“Create HDL Wrapper”。接下来我们还要修改约束文件,根据原理图为 Ethernet1 接口分配引脚。
保存约束文件,然后进行之后操作重新生成 BIT 文件
由于可以与Ethernet0共用同一个工程,所以不需要建立新的工程,不过还是在其基础上有所修改:
在工程的代码文件下将网口改为Ethernet1:
修改lwip库文件:
修改lwip211.mld文件:
根据软件安装路径,我的是在C:\Xilinx\Vitis\2021.1\data\embeddedsw\ThirdParty\sw_services\lwip211_v1_5\data这个路径下:添加以下内容:
BEGIN CATEGORY emio_options PARAM name = emio_options, desc = "Settings for ETH using EMIO in PL"; PARAM name = use_gmii2rgmii_core_on_eth0, desc = "Settings for ETH0 using GMII to RGMII ip core in PL", type = bool, default = false; PARAM name = use_gmii2rgmii_core_on_eth1, desc = "Settings for ETH1 using GMII to RGMII ip core in PL", type = bool, default = false; PARAM name = gmii2rgmii_core_address_on_eth0, desc = "Settings for ETH0's PHY address of GMII to RGMII ip core in PL", type = int, default = 0; PARAM name = gmii2rgmii_core_address_on_eth1, desc = "Settings for ETH1's PHY address of GMII to RGMII ip core in PL", type = int, default = 0; END CATEGORY之后打开BSP,按照下图修改设置值:
修改lwip211.tcl文件(文件路径:C:\Xilinx\Vitis\2021.1\data\embeddedsw\ThirdParty\sw_services\lwip211_v1_5\data),添加如下内容:
xproc generate_lwip_opts {libhandle} { .... # Content added begins # EMIO options set use_gmii2rgmii_core_on_eth0 [common::get_property CONFIG.use_gmii2rgmii_core_on_eth0 $libhandle] set use_gmii2rgmii_core_on_eth1 [common::get_property CONFIG.use_gmii2rgmii_core_on_eth1 $libhandle] set gmii2rgmii_core_address_on_eth0 [common::get_property CONFIG.gmii2rgmii_core_address_on_eth0 $libhandle] set gmii2rgmii_core_address_on_eth1 [common::get_property CONFIG.gmii2rgmii_core_address_on_eth1 $libhandle]
if { $use_gmii2rgmii_core_on_eth0 == true } { puts $lwipopts_fd "\#define XPAR_GMII2RGMIICON_0N_ETH0_ADDR $gmii2rgmii_core_address_on_eth0" } if { $use_gmii2rgmii_core_on_eth1 == true } { puts $lwipopts_fd "\#define XPAR_GMII2RGMIICON_0N_ETH1_ADDR $gmii2rgmii_core_address_on_eth1" } # Content added ends
puts $lwipopts_fd "\#endif" close $lwipopts_fd}同样,修改完之后一定记得右击平台工程进行Build Project:
在V1.1.0的硬件设计中,eth的PHY芯片由RTL8211E更换成RTL8211F。目前vitis中提供的LWIP驱动中,不支持RTL8211F,所以需要修改LWIP的源码。
对应需要修改的文件是C:\Xilinx\Vitis\2021.1\data\embeddedsw\ThirdParty\sw_services\lwip211_v1_5\src\contrib\ports\xilinx\netif\xemacpsif_physpeed.c
xxxxxxxxxx// Add RTL8211F macro definition.
// Modified the get_Realtek_phy_speed function to support RTL8211F.static u32_t get_Realtek_phy_speed(XEmacPs *xemacpsp, u32_t phy_addr){ ... u16_t phy_identity2 = 0; ... xil_printf("autonegotiation complete \r\n");
//Identify PHY model XEmacPs_PhyRead(xemacpsp, phy_addr, PHY_IDENTIFIER_2_REG, &phy_identity2);
switch (phy_identity2) { case PHY_REALTEK_RTL8211F: { xil_printf("detected RTL8211F \r\n"); //Switch to page 0xd08 XEmacPs_PhyWrite(xemacpsp, phy_addr, RTL8211F_PAGSR, RTL8211F_MIICR_PAGE); // enable TXDLY XEmacPs_PhyRead(xemacpsp, phy_addr, RTL8211F_MIICR, &control); XEmacPs_PhyWrite(xemacpsp, phy_addr, RTL8211F_MIICR, control | RTL8211F_TXDLY_MASK);
//Switch to page 0xA43 XEmacPs_PhyWrite(xemacpsp, phy_addr, RTL8211F_PAGSR, RTL8211F_PHYSR_PAGE); XEmacPs_PhyRead(xemacpsp, phy_addr, RTL8211F_PHYSR, &status_speed); //Switch back to default page XEmacPs_PhyWrite(xemacpsp, phy_addr, RTL8211F_PAGSR, 0); //If there is link if (status_speed & RTL8211F_PHYSR_LINK_MASK) { temp_speed = status_speed & RTL8211F_PHYSR_SPEED_MASK;
if (temp_speed == RTL8211F_PHYSR_1000) return 1000; else if(temp_speed == RTL8211F_PHYSR_100) return 100; else return 10; } break; } case PHY_REALTEK_RTL8211E: xil_printf("detected RTL8211E \r\n"); //RTL8211E fall-back to default Realtek behaviour default: { XEmacPs_PhyRead(xemacpsp, phy_addr,IEEE_SPECIFIC_STATUS_REG, &status_speed); if (status_speed & 0x400) { temp_speed = status_speed & IEEE_SPEED_MASK;
if (temp_speed == IEEE_SPEED_1000) return 1000; else if(temp_speed == IEEE_SPEED_100) return 100; else return 10; } break; } } return XST_FAILURE;}修改完之后,重启vitis,并重新编译平台工程。
你也可以从github上下载修改好的lwip压缩包。
编译工程成功后,用type-c USB线将开发板的JTAG和电脑连接,使用另外一根type-c USB线将开发板的PS UART和电脑连接。找一个网线和电脑连接上,在电脑上打开串口调试工具MobaXterm,和开发板的PS UART建立连接。通过串口观察到网络已经启动,并且 网络IP为192.168.3.150,网络端口为port 7。
用相同路由器网段的 WINDOWS电脑(可以用本主机的IP ) ping 一下这个IP 可以ping 通,说明网络连接成功了:
通过网络调试助手连接后,发送什么数据,就能通过网络接收到什么数据(设置的端口号是7,IP地址按照之前串口读到的板子IP地址设置),在电脑端运行个tcp client :